package copy

import (
	"errors"
	"fmt"
	// "io"
	"os"
	"path/filepath"
	"strings"
)

// 立刻返回
func (self *Copyer) Start() {
	self.IsDoing = true

	f := func(path string, info os.FileInfo, err error) error {
		if self.stopFlag {
			return errors.New("Stop")
		}

		defer func() {
			if self.stopFlag {
				return
			}
			self.errMsg = nil
			self.errorType = ERROR_TYPE_NO
		}()

		self.doingName = info.Name()
		if err != nil {
			// 获取信息失败跳过，没有遇到到失败的情况
			// 出错会在文件不存在时，可是前面创建时已经确保文件存在了
			return nil
		}

		newPath := strings.Replace(path, self.srcDir, self.dstDir, 1)
		_, err = os.Stat(newPath)
		if err == nil {
			// 目标文件已经存在，允许跳过，覆盖， 终止复制
			self.errorType = ERROR_TYPE_DST_EXIST
			self.errMsg = errors.New(fmt.Sprintf("%s is exist", newPath))
			switch self.handleError(err) {
			case ERROR_HANDLE_CONTINUE:
				return nil
			case ERROR_HANDLE_STOP:
				return err
			}
		}

		mode := info.Mode().String()
		switch mode[0] {
		case 'L', 'l':
			path, err = os.Readlink(path)
			if err != nil {
				// 目标是个无效的连接, 跳过或者终止
				self.errorType = ERROR_TYPE_INVILD_LINK
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				default:
					return errors.New("error handle : nedd continue or stop")
				}
			}
			// 直接创建一个连接
			err = os.Symlink(path, newPath)
			if err != nil {
				// 创建连接失败 ,
				self.errorType = ERROR_TYPE_CREATE_LINK_F
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				default:
					return errors.New("error handle : nedd continue or stop")
				}

			}
			self.doneSize += info.Size()
		case 'd', 'D':
			err = os.MkdirAll(newPath, info.Mode())
			if err != nil {
				// 创建目录失败
				self.errorType = ERROR_TYPE_CREATE_DIR_F
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				default:
					return errors.New("error handle : nedd continue or stop")
				}
			}
			self.doneSize += info.Size()
		case '-':
			// 打开旧文件
			src, err := os.Open(path)
			if err != nil {
				self.errorType = ERROR_TYPE_OPEN_FILE_F
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				default:
					return errors.New("error handle : nedd continue or stop")

				}
			}
			defer src.Close()

			dst, err := os.Create(newPath)
			if err != nil {
				// 目标文件创建失败，允许跳过， 终止复制
				self.errorType = ERROR_TYPE_CREARE_FILE_F
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				}
			}
			defer dst.Close()

			_, err = self.copy(dst, src)
			if err != nil {
				// 目标文件写入失败，允许跳过， 终止复制
				self.errorType = ERROR_TYPE_WRITE_FILE_F
				self.errMsg = err
				switch self.handleError(err) {
				case ERROR_HANDLE_CONTINUE:
					return nil
				case ERROR_HANDLE_STOP:
					return err
				}
			}
		default:
			// 不支持的源文件类型
			self.errorType = ERROR_TYPE_SRC_TYPE
			self.errMsg = err
			switch self.handleError(err) {
			case ERROR_HANDLE_CONTINUE:
				return nil
			case ERROR_HANDLE_STOP:
				return err
			}
		}

		os.Chmod(newPath, info.Mode())

		self.doneCount++

		return nil
	}
	go func() {
		for _, item := range self.items {
			filepath.Walk(filepath.Join(self.srcDir, item), f)
		}
		self.IsDoing = false
	}()
}

// 获取需要复制内容的详情
// 计算到的大小，数量，当前文件名称， 信息（需要对信息进行判断）
func (self *Copyer) GetCopingInfo() (count, size int64, name, message string) {
	if self.errMsg != nil {
		message = self.errMsg.Error()
		// switch self.errorType {
		// case ERROR_TYPE_WRITE_FILE_F:
		// 	message += ": write error"
		// case ERROR_TYPE_CREARE_FILE_F, ERROR_TYPE_CREATE_DIR_F:
		// 	message += ": create error"
		// case ERROR_TYPE_OPEN_FILE_F:
		// 	message += ": open erroe"
		// }
	}

	return self.doneCount, self.doneSize, self.doingName, message
}
